﻿using System;
using System.Text.RegularExpressions;

namespace Flagwind.Web.Filters
{
	internal static class InputValidationUtility
	{
		#region 常量定义

		private static readonly Regex _regex = new Regex(@"(?'start'<\s*(?'tag'script|form|frameset)[^>]*?>)(?'content'.*?)(?'end'<\s*/\s*\k'tag'\s*>)", (RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture | RegexOptions.Singleline), TimeSpan.FromSeconds(5));
		private static readonly Regex _iframeRegex = new Regex(@"<iframe[^>]+src=[""']?(?'src'[^""']+)[""']?", (RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture | RegexOptions.Singleline), TimeSpan.FromSeconds(5));
		
		#endregion

		#region 公共方法

		public static string Detoxify(string text)
		{
			if(string.IsNullOrWhiteSpace(text))
				return text;

			text = _regex.Replace(text, match =>
			{
				return
					EncodeHtmlTag(match.Groups["start"].Value) +
					match.Groups["content"].Value +
					EncodeHtmlTag(match.Groups["end"].Value);
			});

			text = _iframeRegex.Replace(text, match =>
			{
				var src = match.Groups["src"];

				if(src.Success && (!src.Value.Trim().StartsWith("/")))
					return match.Value.Substring(0, src.Index - match.Index) + "err-illegal-path.html?src=" + src.Value + match.Value.Substring(src.Index - match.Index + src.Length);

				return match.Value;
			});

			return text;
		}

		#endregion

		#region 私有方法

		private static string EncodeHtmlTag(string tag)
		{
			if(string.IsNullOrWhiteSpace(tag))
				return tag;

			return "&lt;" + tag.Substring(1, tag.Length - 2) + "&gt;";
		}

		#endregion
	}
}
